package com.study.service.async;

import com.study.constant.AsyncTaskStatusEnum;
import com.study.vo.AsyncTaskInfo;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * 异步任务执行监控切面
 */
@Slf4j
@Aspect
@Component
public class AysncTaskMonitor {

    //注入异步任务管理器
    @Autowired
    private AsyncTaskManager  asyncTaskManager;

    /**
     * 异步任务执行的环绕切面
     * @param proceedingJoinPoint
     * @return
     */
    @Around("execution(* com.study.service.async.impl.IAsyncServiceImpl.*(..))")
    public Object taskHandler(ProceedingJoinPoint proceedingJoinPoint){

        //获取 taskId
        String taskId = proceedingJoinPoint.getArgs()[1].toString();

        //获取任务信息、在提交任务的时候就已经放入到容器中
        AsyncTaskInfo taskInfo = asyncTaskManager.getTaskInfo(taskId);
        log.info("已经监听的异步任务taskId: [{}]", taskId);

        taskInfo.setStatus(AsyncTaskStatusEnum.RUNNING);
        asyncTaskManager.setTaskInfo(taskInfo);

        AsyncTaskStatusEnum status;
        Object result;

        try {
            //执行异步任务
            result = proceedingJoinPoint.proceed();
            status = AsyncTaskStatusEnum.SUCCESS;
        }catch (Throwable ex){
            //异步任务出现了异常
            result = null;
            status = AsyncTaskStatusEnum.FAILED;
            log.error("异步任务执行监控失败、taskId:[{}]、错误信息：[{}]",
                    taskId,ex.getMessage(),ex);
        }

        //设置异步任务其他的信息、再次重新放入容器中
        taskInfo.setEndTime(new Date());
        taskInfo.setStatus(status);
        taskInfo.setTotalTime(String.valueOf(
                taskInfo.getEndTime().getTime() - taskInfo.getStartTime().getTime()
        ));

        asyncTaskManager.setTaskInfo(taskInfo);

        return result;
    }


}
